const Ble = Ble || {}
Ble.deviceId = ''
Ble.serviceId = '0000F111-0000-1000-8000-00805F9B34FB'
Ble.characteristicId = '0000F113-0000-1000-8000-00805F9B34FB'
Ble.characteristicIdWrite = '0000F112-0000-1000-8000-00805F9B34FB'
Ble.context = null
Ble.startConnect = function (_this) {
    this.context = _this
    wx.openBluetoothAdapter({
        success: res => {
			this.context.setData({ isBlueToothOpen: true })
			this.getBluetoothAdapterState()
        },
        fail: err => {
			this.context.setData({ isBlueToothOpen: false })
        }
    })
    wx.onBluetoothAdapterStateChange(res => {
        if (res.available) {
            this.getBluetoothAdapterState()
        }
    })
}
// 获取本机蓝牙适配器状态

Ble.getBluetoothAdapterState = function () {
    wx.getBluetoothAdapterState({
        success: res => {
            console.log(res)
            if (!res.available) {
                wx.showToast({ title: '设备无法开启蓝牙连接', duration: 2000 })
                setTimeout(() => { wx.hideToast() }, 2000)
            } else {
                if (!res.discovering) this.startBluetoothdeviceDiscovery()
            }
        }
    })
}
// 开始搜索蓝牙设备
Ble.startBluetoothdeviceDiscovery = function () {
    wx.startBluetoothDevicesDiscovery({
        services: [this.serviceId],
        allowDuplicatesKey: false,
        success: res => {
            console.log(res)
            if (!res.isDiscovering) {
                this.getBluetoothAdapterState()
            } else {
                this.onBluetoothDeviceFound()
            }
        },
        fail: err => {
            console.log(err)
            this.stopBluetoothDevicesDiscovery()
            this.context.setData({ isFoundDevice: false })
        }
    })
}
// 监听寻找到新设备的事件
Ble.onBluetoothDeviceFound = function () {
    wx.onBluetoothDeviceFound(res => {
        console.log('设备已搜索到', res.devices)
        wx.hideLoading()
        this.context.setData({ isFoundDevice: true })
        if (res.devices[0].deviceId) {
			this.deviceId = res.devices[0].deviceId
			this.startConnectDevices()
		}
    })
}
// 开始连接要配对的设备
Ble.startConnectDevices = function () {
    this.stopBluetoothDevicesDiscovery()
	wx.createBLEConnection({
		deviceId: this.deviceId,
        success: res => {
            console.log('开始连接要配对的设备', res)
            if (res.errCode == 0) {
                this.notifyBLECharacteristicValueChange(this.deviceId, this.serviceId, this.characteristicId)
                setTimeout(() => {
					this.writeBLECharacteristicValue(this.deviceId, this.serviceId, this.syncTime()).then(result => {
						console.log('发送同步成功：', result)
					})
                }, 1000)
            }
        },
        fail: err => {
            console.log('配对失败：', err)
            wx.showToast({ title: '配对失败', duration: 2000 })
			this.startConnectDevices()
            setTimeout(function () { wx.hideToast() }, 2000)
        }
    })
}
/** 
 * 向低功耗蓝牙设备特征值中写入二进制数据。注意：必须设备的特征值支持write才可以成功调用，具体参照 characteristic 的 properties 属性
 * tips: 并行调用多次读写接口存在读写失败的可能性
 */
Ble.writeBLECharacteristicValue = function (deviceId, serviceId, buffer) {
	return new Promise((resolve, reject) => {
		wx.writeBLECharacteristicValue({
			deviceId, // 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
			serviceId, // 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
			characteristicId: this.characteristicIdWrite, // 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
			value: buffer, // 这里的value是ArrayBuffer类型
			success: res => { resolve(res) },
			fail: err => { reject(err) }
		})
	})
}
// 启用低功耗蓝牙设备特征值变化时的 notify 功能，订阅特征值。注意：必须设备的特征值支持notify或者indicate才可以成功调用
Ble.notifyBLECharacteristicValueChange = function (deviceId, serviceId, characteristicId) {
    wx.notifyBLECharacteristicValueChange({
        state: true, // 启用 notify 功能 
        deviceId, // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
        serviceId, // 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
        characteristicId, // 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
        success: res => {
            console.log('监听成功：', res)
            this.onBLECharacteristicValueChange()
        }
    })
}
Ble.onBLECharacteristicValueChange = function () {
    wx.onBLECharacteristicValueChange(res => {
        console.log(this.ab2hex(res.value))
		const command = this.ab2hex(res.value).substr(6, 2)
		console.log(command)
		if (command == '02') {
			this.writeBLECharacteristicValue(this.deviceId, this.serviceId, this.setParam()).then(result => {
				console.log('发送设置参数成功：', result)
			})
		}
        this.stopBluetoothDevicesDiscovery()
    })
}
// 停止蓝牙搜索
Ble.stopBluetoothDevicesDiscovery = function () {
    wx.stopBluetoothDevicesDiscovery({
        success: (res) => {
            console.log(res)
            wx.hideLoading()
        }
    })
}
// 同步时间
Ble.syncTime = function() {
	// 向蓝牙设备发送一个0x00的16进制数据
	const buffer = new ArrayBuffer(9)
	const view = new DataView(buffer, 0, 3)
	const dataView = new DataView(buffer, 3, 5)
	const sumCheckView = new DataView(buffer, 8, 1)
	const time = parseInt(+new Date() / 1000)
	view.setUint8(0, 0x55) // (max signed 8-bit integer)
	view.setUint8(1, 0xaa)
	view.setUint8(2, 0x05)
	dataView.setUint8(0, 0x02)
	dataView.setUint32(1, time, true)  // 字节序，true为小端字节序，false或者不填为大端字节序
	sumCheckView.setUint8(0, this.sumCheck(dataView))  // 设置和校验值
	return buffer
}
// 设置参数
Ble.setParam = function() {
	const buffer = new ArrayBuffer(8)
	const view = new DataView(buffer, 0, 3)
	const dataView = new DataView(buffer, 3, 4)
	const sumCheckView = new DataView(buffer, 7, 1)
	view.setUint8(0, 0x55)
	view.setUint8(1, 0xaa)
	view.setUint8(2, 0x04)
	dataView.setUint8(0, 0x04)
	dataView.setUint8(1, 0x64) // 设置为100
	dataView.setUint8(2, 0x00)
	dataView.setUint8(3, 0x00)
	sumCheckView.setUint8(0, this.sumCheck(dataView))
	console.log('设置参数',this.ab2hex(buffer))
	return buffer
}
// 启动/停止心率测量
Ble.startHeartRate = function () {
	const buffer = new ArrayBuffer(8)
	const view = new DataView(buffer, 0, 3)
	const dataView = new DataView(buffer, 3, 4)
	const sumCheckView = new DataView(buffer, 7, 1)
}
// ArrayBuffer转16进度字符串示例
Ble.ab2hex = function (buffer) {
    let hexArr = Array.prototype.map.call(new Uint8Array(buffer), 
    bit => ('00' + bit.toString(16)).slice(-2))
    return hexArr.join('')
}
// 和校验
Ble.sumCheck = function (dataView) {
	let sum_check = 0
	for (let i = 0; i < dataView.byteLength; i++) {
		sum_check ^= dataView.getUint8(i)
	}
	return sum_check
}
export default Ble